from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTextEdit, QPushButton
from PyQt5.QtGui import QPainter, QTextDocument, QTextCursor
from PyQt5.QtPrintSupport import QPrintPreviewDialog, QPrinter


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Print Example")

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.layout = QVBoxLayout(self.central_widget)

        self.text_edit = QTextEdit()
        self.layout.addWidget(self.text_edit)

        self.print_button = QPushButton("Print")
        self.print_button.clicked.connect(self.print_document)
        self.layout.addWidget(self.print_button)

        self.preview_button = QPushButton("Print Preview")
        self.preview_button.clicked.connect(self.preview_document)
        self.layout.addWidget(self.preview_button)

        self.document = QTextDocument()

    def print_document(self):
        printer = QPrinter()
        printer.setPageSize(QPrinter.A4)

        dialog = QPrintPreviewDialog(printer, self)
        dialog.paintRequested.connect(self.print_preview)

        dialog.exec_()

    def print_preview(self, printer):
        self.document.setHtml(self.text_edit.toPlainText())

        self.document.print_(printer)

    def preview_document(self):
        printer = QPrinter()
        printer.setPageSize(QPrinter.A4)

        dialog = QPrintPreviewDialog(printer, self)
        dialog.paintRequested.connect(self.preview)

        dialog.exec_()

    def preview(self, printer):
        self.document.setHtml(self.text_edit.toPlainText())

        painter = QPainter(printer)
        painter.setRenderHint(QPainter.Antialiasing)
        self.document.drawContents(painter)
        painter.end()


if __name__ == "__main__":
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()